package net.borlis.sample.services.facade.api;

import net.borlis.dictionaries.product.DeprecatedProductType;
import net.borlis.dictionaries.product.HierarchyLevelDictionary;
import net.borlis.dictionaries.product.LifecycleStateDictionary;
import net.borlis.sample.service.entities.history.HistoryFilter;
import net.borlis.sample.services.api.IHistoryService;
import net.borlis.sample.services.api.ILifecycleService;
import net.borlis.sample.services.api.IProviderSettingsService;
import net.borlis.sample.services.api.IVitoService;
import net.borlis.sample.services.declaration.*;
import net.borlis.sample.services.declaration.common.LocaleObject;
import net.borlis.sample.services.declaration.output.*;
import net.borlis.sample.services.facade.ws.request.*;
import net.borlis.sample.services.facade.ws.response.*;
import net.borlis.sample.services.facade.ws.response.util.IBuilderViewData;
import net.borlis.sample.services.input.VitoCodesFilter;
import net.borlis.sample.services.input.VitoIdsFilter;
import net.borlis.sample.services.output.*;
import net.borlis.errors.annotations.RequestLocale;
import net.borlis.errors.annotations.TranslatedExceptionRegister;
import net.borlis.log.SimpleLogger;
import net.borlis.scheduler.lifecycle.UploadStatus;
import net.borlis.scheduler.manager.IQuartzManager;
import net.borlis.validation.NotNull;
import net.borlis.validation.Validate;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import java.util.*;

import static net.borlis.dictionaries.product.LifecycleStateDictionary.WORKING_COPY;

/**
 * The bridge implementation to the dynamix-service data container.
 *
 * @author alex@borlis.net
 */
@RequestScoped
public class DataProducer implements IDataProducer {

    @Inject //@Alpha
    private CatalogService catalogService;

    @Inject //@Alpha
    private IVitoService vitoService;

    @Inject //@Alpha
    private ILifecycleService lifecycleService;

    @Inject
    private IQuartzManager quartz;

    @Inject //@Alpha
    private IHistoryService historyService;

    @Inject //@Alpha
    private TravelPeriodService travelPeriodService;

    @Inject
    private IBuilderViewData builder;

    @Inject //@Alpha
    private IProviderSettingsService providerSettingsService;

    @Inject //@Alpha
    private VitoAddressService vitoAddressService;

    @Inject //@Alpha
    private BankDetailService bankDetailService;

    @Inject //@Alpha
    private CreditCardDetailService creditCardDetailService;

    @Inject //@Alpha
    private ProviderBookingInfoService providerBookingInfoService;

    @Inject //@Alpha
    private BookingConfigService bookingConfigService;

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger
    public List<CreditCardTypeObject> getCreditCardTypes(@RequestLocale String locale) /* throws TranslatedException */ {
        return catalogService.getCreditCardTypes(locale);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger
    public List<LocaleObject> getLocales(@RequestLocale String locale) /* throws TranslatedException */ {
        return catalogService.getAllLocales();
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger
    public List<CountryCurrencyObject> getCountries(@RequestLocale String locale) /* throws TranslatedException */ {
        return catalogService.getAllCountries(locale);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger
    public List<HierarchyLevelObject> getHierarchyLevels(@RequestLocale String locale) /* throws TranslatedException */ {
        return catalogService.getHierarchyLevels(locale);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger
    public List<BookingConfigStrategyObject> getBookingConfigStrategies(@RequestLocale String locale) /* throws TranslatedException */ {
        return catalogService.getBookingConfigStrategies(locale);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger  @Validate
    public List<VitoResponse> getVitosByFilter(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, Set<Long> vitos,
                                               Set<Long> countries, Set<Long> flights,
                                               Set<Long> hotels, @NotNull Long userId) /* throws TranslatedException */ {
        List<VitoResponse> result = new ArrayList<>();
        VitoIdsFilter filter = new VitoIdsFilter(vitos, countries, flights, hotels);
        List<VitoFilteredLocalized> vitoLocalizedList = vitoService.getVitos(state, locale, filter, userId);
        for (VitoFilteredLocalized ve : vitoLocalizedList) {
            result.add(builder.createVitoViewData(ve)); //todo:: optimize with named query?
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<VitoResponse> getVitosByFilter(@NotNull LifecycleStateDictionary state,
                                               @RequestLocale String locale, Set<String> vitos, Set<String> countries, Set<String> flights,
                                               Set<String> hotels, @NotNull long userId) /* throws TranslatedException */ {
        List<VitoResponse> result = new ArrayList<>();
        VitoCodesFilter filter = new VitoCodesFilter(vitos, countries, flights, hotels);
        List<VitoFilteredLocalized> vitoLocalizedList = vitoService.getVitos(state, locale, filter, userId);
        for (VitoFilteredLocalized ve : vitoLocalizedList) {
            result.add(builder.createVitoViewData(ve)); //todo:: optimize with named query?
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoWithProvidersResponse getVito(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long vitoId, Long userId)
            /* throws TranslatedException */ {
        VitoFilteredLocalized serviceResult = vitoService.getVito(state, locale, vitoId, userId);
        return builder.createVitoWithProvidersViewData(serviceResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderResponse> getHotelProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                       @NotNull Long userId)
            /* throws TranslatedException */ {
        return getProviderList(state, locale, DeprecatedProductType.HOTEL, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderResponse> getFlightProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long userId)
            /* throws TranslatedException */ {
        return getProviderList(state, locale, DeprecatedProductType.FLIGHT, userId);
    }

    /**
     * {@inheritDoc}
     */
    @TranslatedExceptionRegister @SimpleLogger @Validate
    private List<ProviderResponse> getProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, DeprecatedProductType type,
                                                   @NotNull Long userId) /* throws TranslatedException */ {
        List<ProviderResponse> result = new ArrayList<>();
        List<ProviderLocalized> providerLocalizedList = vitoService.getProviders(state, locale, type, userId);
        for (ProviderLocalized pe : providerLocalizedList) {
            result.add(builder.createProviderViewData(pe));
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoWithProvidersResponse createVito(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                VitoCreateRequest request, @NotNull Long userId) /* throws TranslatedException */ {
        vitoService.createVito(state, locale, request.getCode(),
                request.getName(), request.getKid(),
                request.getCountryCode(), userId, request.getFirstFixedMargin(), request.getRelativeMargin(),
                request.getSecondFixedMargin(), request.getReleaseDays(),
                builder.createTravelDurations(request.getTravelDurations()));
        VitoFilteredLocalized serviceResult = vitoService.getVito(state, locale, request.getCode(), userId);
        return builder.createVitoWithProvidersViewData(serviceResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void configureVitoProvider(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                      ConfigureVitoProviderRequest confReq, @NotNull Long userId)
            /* throws TranslatedException */ {
        vitoService.configureProvider(state, locale, confReq.getVitoId(), confReq.getProviderId(),
                confReq.getEnabled(), confReq.getSaleType(), userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoFilterResponse getVitoFilter(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long userId)
            /* throws TranslatedException */ {
        FilterLocalized serviceResult = vitoService.getVitoFilter(state, locale, userId);
        return builder.createVitoFilterViewData(serviceResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderResponse> getHotelProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, Long vitoId,
                                                       @NotNull Long userId) /* throws TranslatedException */ {
        return getProviderList(state, locale, DeprecatedProductType.HOTEL, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderResponse> getFlightProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, Long vitoId,
                                                        @NotNull Long userId) /* throws TranslatedException */ {
        return getProviderList(state, locale, DeprecatedProductType.FLIGHT, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public Map<LifecycleStateDictionary, GetLifecycleStateResponse> getConfigurations(@RequestLocale String locale, @NotNull Long vitoId,
                                                                                      @NotNull Long userId)
            /* throws TranslatedException */ {
        return builder.createLifeCycleConfigurationsViewData(lifecycleService.getConfigurations(WORKING_COPY,
                locale, vitoId, userId));
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void revertConfiguration(@RequestLocale String locale, @NotNull Long vitoId, @NotNull Long userId, @NotNull LifecycleStateDictionary stateFrom) /* throws TranslatedException */ {
        switch (stateFrom) {
            case LAST_LIVE: {
                lifecycleService.revertFromLastLive(vitoId, userId);
                break;
            }
            case LIVE_COPY: {
                lifecycleService.revertFromLive(vitoId, userId);
                break;
            }
            case WAITING_FOR_UPLOAD: {
                lifecycleService.revertFromWaitingForUpload(vitoId, userId);
                break;
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void restoreConfiguration(@RequestLocale String locale, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        lifecycleService.restoreLastLive(vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void upload(@RequestLocale String locale, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        lifecycleService.upload(vitoId, userId);
        quartz.scheduleUpload(new Date((new Date().getTime() + Calendar.MINUTE)), locale, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<BaseVitoResponse> getUserVitoList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long userId)
            /* throws TranslatedException */ {
        return builder.createBaseVitoViewDataList(vitoService.getVitos(state, locale, userId));
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public UploadStatusResponse getUploadStatus(@RequestLocale String locale, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        UploadStatus us = quartz.getUploadStatus(locale, vitoId, userId);
        return builder.createUploadStatusViewData(us);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void rescheduleUpload(@RequestLocale String locale, @NotNull Long vitoId, @NotNull  Long userId, Long date)
            /* throws TranslatedException */ {
        Date runDate = new Date(date);
        quartz.scheduleUpload(runDate, locale, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void abortUpload(@RequestLocale String locale, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        quartz.abortUpload(locale, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @TranslatedExceptionRegister @SimpleLogger @Validate
    private List<ProviderResponse> getProviderList(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull DeprecatedProductType type,
                                                   @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        List<ProviderResponse> result = new ArrayList<>();
        List<ProviderLocalized> providerLocalizedList = vitoService.getVitoProviders(state, locale,
                type, vitoId, userId);
        for (ProviderLocalized pe : providerLocalizedList) {
            result.add(builder.createProviderViewData(pe));
        }
        return result;
    }

    /**
     * Implementation of searching method for front services
     * <p/>
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public GetHistoryResponseContainer getHistoryByParams(HistoryFilterView request, @NotNull Long vitoId, @NotNull Long userId,
                                                          @RequestLocale String locale) /* throws TranslatedException */ {
        HistoryFilter filter = builder.createHistoryFilterByRequest(request, vitoId, userId, locale);
        return builder.createHistoryResponse(historyService.getHistoryByFilter(filter));
    }


    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<TravelPeriodObject> getTravelPeriods(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                     @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return travelPeriodService.getTravelPeriods(state, locale, vitoId, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public TravelPeriodObject getTravelPeriod(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                              @NotNull Long id, @NotNull Long userId)
            /* throws TranslatedException */ {
        return travelPeriodService.getTravelPeriod(state, locale, id, userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public TravelPeriodObject createTravelPeriod(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                 TravelPeriodCreateRequest tpReq, @NotNull Long vitoId, @NotNull Long userId)
            /* throws TranslatedException */ {
        return travelPeriodService.createTravelPeriod(state, locale, vitoId, tpReq.getName(), new Date(tpReq.getStartDate()), userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public TravelPeriodObject updateTravelPeriod(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                 TravelPeriodUpdateRequest tpReq, @NotNull Long userId) /* throws TranslatedException */ {
        return travelPeriodService.updateTravelPeriod(state, locale,
                tpReq.getId(), tpReq.getName(), new Date(tpReq.getStartDate()), userId);
    }

    /**
     * {@inheritDoc}
     */
    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public Boolean deleteTravelPeriod(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                      @NotNull Long travelPeriodId, @NotNull Long userId) /* throws TranslatedException */ {
        travelPeriodService.deleteTravelPeriod(state, locale, travelPeriodId, userId);
        return Boolean.TRUE;
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<IdLabelResponse> getHistoryActionTypes(Long elementType, Long resultType, @NotNull Long vitoId, @NotNull Long userId,
                                                       @RequestLocale String locale) /* throws TranslatedException */ {
        return builder.buildActionTypes(historyService.actionTypes(elementType, resultType, vitoId,
                userId, locale));
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<IdLabelResponse> getHistoryElementTypes(Long menuItem, Long resultType, @NotNull Long vitoId, @NotNull Long userId,
                                                        @RequestLocale String locale) /* throws TranslatedException */ {
        return builder.createElementTypes(historyService.elementTypes(menuItem,
                resultType, vitoId, userId, locale), locale);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<IdLabelResponse> getMenuItems(Long elementType, Long elementName, @RequestLocale String locale, @NotNull Long vitoId,
                                              @NotNull Long userId) /* throws TranslatedException */ {
        return builder.buildMenuItemsResponse(historyService.getMenuItems(elementType, elementName,
                locale, vitoId, userId), locale);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public HistoryFilterView getFilterForConfiguration(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                       @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return builder.buildViewFilterForLifecycleConfiguration(
                historyService.getFilterForConfigurationState(state, locale, vitoId, userId));
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public Set<IdLabelResponse> getResultTypes(Long elementType, Long menuItem, @RequestLocale String locale, @NotNull Long vitoId,
                                               @NotNull Long userId) /* throws TranslatedException */ {
        return builder.createResultTypes(historyService.historyElements(elementType,
                menuItem, locale, vitoId, userId), locale);
    }

    // -=-=-=-=-

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<TravelPeriodObject> createTravelPeriodWithCopy(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                               TravelPeriodCreateWithCopyRequest request,
                                                               @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return travelPeriodService.createTravelPeriodWithCopy(state, locale, vitoId, userId,
                request.getTravelPeriodToCopy(), request.getName(), request.getStartDate(),
                request.getHierarchyLevels());
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public TravelPeriodObject createTravelPeriod(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                 TravelPeriodCreateWithCopyRequest request,
                                                 @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return travelPeriodService.createTravelPeriod(state, locale, vitoId, userId,
                request.getTravelPeriodToCopy(), request.getName(), request.getStartDate(),
                request.getHierarchyLevels());
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<VitoAddressObject> getVitoAddresses(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long vitoId,@NotNull Long userId) /* throws TranslatedException */ {
        return vitoAddressService.getVitoAddresses(state, locale, vitoId, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoAddressObject getVitoAddress(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,@NotNull Long vaId, @NotNull Long userId) /* throws TranslatedException */ {
        return vitoAddressService.getVitoAddress(state, locale, vaId, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoAddressObject createVitoAddress(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                               VitoAddressCreateRequest vaReq, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return vitoAddressService.createVitoAddress(state, locale, vitoId,
                vaReq.getCountryCode(), vaReq.getTitle(), vaReq.getSalutation(),
                vaReq.getFirstName(), vaReq.getLastName(), vaReq.getStreet(), vaReq.getZipCode(),
                vaReq.getCity(), vaReq.getTelephone(), vaReq.getFax(), vaReq.getMobile(), vaReq.getEmail(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public VitoAddressObject updateVitoAddress(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                               VitoAddressUpdateRequest vaReq, @NotNull Long userId) /* throws TranslatedException */ {
        return vitoAddressService.updateVitoAddress(state, locale,
                vaReq.getId(), vaReq.getCountryCode(), vaReq.getTitle(), vaReq.getSalutation(),
                vaReq.getFirstName(), vaReq.getLastName(), vaReq.getStreet(), vaReq.getZipCode(),
                vaReq.getCity(), vaReq.getTelephone(), vaReq.getFax(), vaReq.getMobile(), vaReq.getEmail(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void deleteVitoAddress(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long vaId, @NotNull Long userId) /* throws TranslatedException */ {
        vitoAddressService.deleteVitoAddress(state, locale, vaId, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<BankAccountObject> getBankAccounts(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                           @NotNull Long vitoId, String holder, @NotNull Long userId) /* throws TranslatedException */ {
        return bankDetailService.getBankDetails(state, locale, vitoId, holder, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public BankAccountObject getBankAccount(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long baId, @NotNull Long userId) /* throws TranslatedException */ {
        return bankDetailService.getBankDetail(state, locale, baId, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public BankAccountObject createBankAccount(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, BankAccountCreateRequest baReq, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        return bankDetailService.createBankDetail(state, locale, vitoId,
                baReq.getAccountHolderFirstName(), baReq.getAccountHolderLastName(),
                baReq.getAccountNumber(), baReq.getBankCode(), baReq.getBank(), baReq.getBic(), baReq.getIban(),
                userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public BankAccountObject updateBankAccount(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, BankAccountUpdateRequest baReq,
                                               @NotNull Long userId) /* throws TranslatedException */ {
        return bankDetailService.updateBankDetail(state, locale,
                baReq.getId(), baReq.getAccountHolderFirstName(),
                baReq.getAccountHolderLastName(), baReq.getAccountNumber(),
                baReq.getBankCode(), baReq.getBank(), baReq.getBic(),
                baReq.getIban(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void deleteBankAccount(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long id, @NotNull Long userId) /* throws TranslatedException */ {
        bankDetailService.deleteBankDetail(state, locale, id, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<CreditCardObject> getCreditCards(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                 @NotNull Long vitoId, String holder, @NotNull Long userId) /* throws TranslatedException */ {
        return creditCardDetailService.getCreditCardDetails(state, locale, vitoId, holder, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public CreditCardObject createCreditCard(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                             CreditCardCreateRequest request, @NotNull Long vitoId, @NotNull Long userId)
            /* throws TranslatedException */ {
        return creditCardDetailService.createCreditCardDetail(state, locale, vitoId,
                request.getCardType(), request.getAccountHolderFirstName(), request.getAccountHolderLastName(),
                request.getCardNumber(), request.getCvc(), request.getIssueNumber(),
                request.getIssueDate(), request.getExpiresEnd(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public void deleteCreditCard(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long id, @NotNull Long userId) /* throws TranslatedException */ {
        creditCardDetailService.deleteCreditCardDetail(state, locale, id, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public CreditCardObject updateCreditCard(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull CreditCardUpdateRequest request, @NotNull Long userId) /* throws TranslatedException */ {
        return creditCardDetailService.updateCreditCardDetail(state, locale,
                request.getId(),
                request.getCardType(), request.getAccountHolderFirstName(), request.getAccountHolderLastName(),
                request.getCardNumber(), request.getCvc(), request.getIssueNumber(),
                request.getIssueDate(), request.getExpiresEnd(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public CreditCardObject getCreditCard(@NotNull LifecycleStateDictionary state, @RequestLocale String locale, @NotNull Long id, @NotNull Long userId) /* throws TranslatedException */ {
        return creditCardDetailService.getCreditCardDetail(state, locale, id, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderBookingObject> getProviderBookingInfo(@NotNull Long vitoId, @NotNull Long userId, @RequestLocale String locale, @NotNull LifecycleStateDictionary state,
                                                              @NotNull DeprecatedProductType type, String providerCode) /* throws TranslatedException */ {
        return providerBookingInfoService.getProviderBookingInfo(state, locale, vitoId, type, providerCode, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public ProviderBookingObject updateProviderBookingInfo(@NotNull Long vitoId, @NotNull Long userId, @RequestLocale String locale,
                                                           @NotNull LifecycleStateDictionary state,
                                                           ProviderBookingInfoUpdateRequest psReq) /* throws TranslatedException */ {
        return providerBookingInfoService.updateProviderBookingInfo(state, locale,
                psReq.getId(), psReq.getProviderCode(), psReq.getAddressId(), psReq.getPaymentType(),
                psReq.getPaymentId(), psReq.getState(), psReq.getBc(), psReq.getBq(), psReq.getNx(), userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<BookingConfigObject> getBookingConfig(@NotNull Long vitoId, @NotNull Long userId, @RequestLocale String locale, @NotNull LifecycleStateDictionary state,
                                                      Set<String> hpc, Set<String> fpc) /* throws TranslatedException */ {
        return bookingConfigService.getBookingConfig(state, locale, vitoId, hpc, fpc, userId);
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public Boolean updateBookingConfig(@NotNull Long vitoId, @NotNull Long userId, @RequestLocale String locale, @NotNull LifecycleStateDictionary state,
                                       BookingConfigUpdateRequest bcReq) /* throws TranslatedException */ {
        bookingConfigService.updateBookingConfig(state, locale,
                vitoId, bcReq.getHotelProviderCode(),  bcReq.getFlightProviderCode(), bcReq.getStrategyCode(), userId);
        return Boolean.TRUE;
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<PortfolioSettingResponse> getPortfolioSettings(@NotNull Long vitoId, @NotNull Long userId, @RequestLocale String locale,
                                                               Set<HierarchyLevelDictionary> hierarchies,
                                                               @NotNull LifecycleStateDictionary state) /* throws TranslatedException */ {
        List<PortfolioSettingResponse> data = new ArrayList<>();
        for (PortfolioSettingLocalized ps : providerSettingsService.getPortfolioSettings(state, locale,
                hierarchies, vitoId, userId)) {
            data.add(builder.createPortfolioSettingViewData(ps));
        }
        return data;
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public Boolean updatePortfolioSettings(@NotNull Long userId, @RequestLocale String locale,
                                           PortfolioSettingUpdateRequest settingRequest,
                                           @NotNull LifecycleStateDictionary state) /* throws TranslatedException */ {
        List<TravelDurationRequest> rtds = settingRequest.getTravelDurations();
        List<TravelDurationLocalized> paramTd = new ArrayList<>();
        for (TravelDurationRequest rtd : rtds) {
            paramTd.add(new TravelDurationLocalized(rtd.getFrom(), rtd.getTo()));
        }
        providerSettingsService.updatePortfolioSettings(state, locale,
                settingRequest.getTravelPeriodId(), settingRequest.getHierarchyLevels(),
                settingRequest.getReleaseDays(), settingRequest.getFirstFixedMargin(),
                settingRequest.getSecondFixedMargin(), settingRequest.getRelativeMargin(),
                settingRequest.getPackaging(), paramTd, userId);
        return Boolean.TRUE;
    }

    @Override @TranslatedExceptionRegister @SimpleLogger @Validate
    public List<ProviderResponse> getActiveProviders(@NotNull LifecycleStateDictionary state, @RequestLocale String locale,
                                                     DeprecatedProductType type, @NotNull Long vitoId, @NotNull Long userId) /* throws TranslatedException */ {
        List<ProviderResponse> result = new ArrayList<>();
        List<ProviderLocalized> providerLocalizedList = vitoService.getActiveVitoProviders(
                state, locale, type, vitoId, userId);
        for (ProviderLocalized pe : providerLocalizedList) {
            result.add(builder.createProviderViewData(pe));
        }
        return result;
    }

}
